Skip to main content

Understanding shell scripts

Shell scripting is a powerful tool for automating tasks in a Unix-like operating system. In this beginner's guide, we'll cover the fundamental concepts and techniques for writing shell scripts, starting from input and output operations, working with if conditions, loops, and functions. Let's begin:

Table of Contents

  1. Introduction to Shell Scripting

    • What is a Shell Script?
    • Why Use Shell Scripts?
  2. Getting Started

    • Setting Up Your Environment
    • Writing Your First Shell Script
    • Executing Shell Scripts
  3. Input and Output

    • User Input (read)
    • Command-Line Arguments
    • Displaying Output (echo)
  4. Variables and Data Types

    • Variable Declaration
    • Basic Data Types (Strings, Integers)
    • Variable Assignment and Manipulation
  5. Conditional Statements

    • if Statements
    • elif (Else If) Statements
    • else Statements
    • Comparison Operators (==, !=, <, >, <=, >=)
  6. Loops

    • for Loops
    • while Loops
    • Loop Control Statements (break, continue)
  7. Functions

    • Defining Functions
    • Passing Arguments to Functions
    • Returning Values from Functions
  8. Arrays

    • Creating and Initializing Arrays
    • Accessing Array Elements
    • Looping Through Arrays
  9. File Operations

    • Reading Files (cat, less, redirection)
    • Writing to Files (echo, redirection)
    • Checking File Existence (test)
  10. Error Handling

    • Exit Codes (return codes)
    • Handling Errors with if Statements
  11. Common Unix Commands

    • Running External Commands (``)
    • Pipelines (|)
    • Command Substitution ($())
  12. Best Practices

    • Commenting Your Code
    • Indentation
    • Error Handling
    • Modularity

1. Introduction to Shell Scripting

What is a Shell Script?

A shell script is a text file containing a series of commands that can be executed by a Unix-like shell (e.g., Bash). It allows you to automate tasks, manage files, and perform various system operations.

Why Use Shell Scripts?

  • Automation of repetitive tasks.
  • Streamlining system administration.
  • Batch processing and data manipulation.
  • Creating custom command-line tools.

2. Getting Started

Setting Up Your Environment

Make sure you have a Unix-like operating system (e.g., Linux, macOS) with a shell (e.g., Bash) installed. You can create and edit shell scripts using a text editor like Vim, Nano, or VSCode.

Writing Your First Shell Script

Create a file with a .sh extension (e.g., my_script.sh) and add the following code:

#!/bin/bash
# This is a comment
echo "Hello, World!"

Executing Shell Scripts

Make the script executable:

chmod +x my_script.sh

Run the script:

./my_script.sh

You should see "Hello, World!" printed to the terminal.

3. Input and Output

User Input (read)

#!/bin/bash
echo "Enter your name: "
read name
echo "Hello, $name!"

Command-Line Arguments

#!/bin/bash
echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"

Run the script with arguments:

./my_script.sh arg1 arg2

Displaying Output (echo)

#!/bin/bash
message="This is a message."
echo $message

4. Variables and Data Types

Variable Declaration

#!/bin/bash
name="John"
age=30

Basic Data Types (Strings, Integers)

#!/bin/bash
string="Hello, World!"
number=42

Variable Assignment and Manipulation

#!/bin/bash
name="John"
name+=" Doe"
echo "Full Name: $name"

5. Conditional Statements

if Statements

#!/bin/bash
if [ "$age" -ge 18 ]; then
echo "You are an adult."
else
echo "You are a minor."
fi

elif (Else If) Statements

#!/bin/bash
if [ "$score" -ge 90 ]; then
echo "Grade: A"
elif [ "$score" -ge 80 ]; then
echo "Grade: B"
else
echo "Grade: C"
fi

else Statements

#!/bin/bash
if [ -e "$file" ]; then
echo "File exists."
else
echo "File does not exist."
fi

Comparison Operators (==, !=, <, >, <=, >=)

#!/bin/bash
if [ "$a" -eq "$b" ]; then
echo "a is equal to b."
fi

6. Loops

for Loops

#!/bin/bash
for fruit in apple banana cherry; do
echo "Fruit: $fruit"
done

while Loops

#!/bin/bash
count=1
while [ $count -le 5 ]; do
echo "Count: $count"
((count++))
done

Loop Control Statements (break, continue)

#!/bin/bash
for num in {1..10}; do
if [ $num -eq 5 ]; then
break
fi
echo "Number: $num"
done

7. Functions

Defining Functions

#!/bin/bash
greet() {
echo "Hello, $1!"
}

Passing Arguments to Functions

#!/bin/bash
greet() {
echo "Hello, $1!"
}
greet "Alice"

Returning Values from Functions

#!/bin/bash
add() {
result=$(( $1 + $2 ))
echo $result
}
sum=$(add 5 3)
echo "Sum: $sum"

8. Arrays

Arrays are a way to store multiple values in a single variable. In shell scripting, you can use arrays to manage lists of items or data. Here's how to work with arrays:

Creating and Initializing Arrays

#!/bin/bash
fruits=("apple" "banana" "cherry")

Accessing Array Elements

#!/bin/bash
fruits=("apple" "banana" "cherry")
echo "First fruit: ${fruits[0]}"
echo "Second fruit: ${fruits[1]}"

Looping Through Arrays

#!/bin/bash
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
echo "Fruit: $fruit"
done

9. File Operations

Shell scripting often involves reading from and writing to files. Here's how to perform basic file operations:

Reading Files

#!/bin/bash
# Using 'cat' to display the contents of a file
cat file.txt

# Using 'less' to view a file interactively
less file.txt

# Redirecting file contents to a variable
content=$(<file.txt)
echo "$content"

Writing to Files

#!/bin/bash
# Using 'echo' to write to a file (overwrite existing content)
echo "Hello, World!" > output.txt

# Using '>>' to append to a file
echo "Appended text." >> output.txt

Checking File Existence

#!/bin/bash
file="example.txt"
if [ -e "$file" ]; then
echo "$file exists."
else
echo "$file does not exist."
fi

10. Error Handling

In shell scripting, you can handle errors using exit codes and conditional statements. Exit codes are numeric values returned by scripts to indicate success or failure (0 typically means success).

Exit Codes (Return Codes)

#!/bin/bash
command_that_might_fail
if [ $? -eq 0 ]; then
echo "Command succeeded."
else
echo "Command failed."
fi

Handling Errors with if Statements

#!/bin/bash
if ! command_that_might_fail; then
echo "Error: Command failed."
fi

11. Common Unix Commands

Running External Commands (``)

You can run external commands and capture their output or assign it to variables using backticks or the $() syntax:

#!/bin/bash
current_date=`date`
echo "Current date and time: $current_date"

OR

#!/bin/bash
current_date=$(date)
echo "Current date and time: $current_date"

Pipelines (|)

Pipelines allow you to pass the output of one command as the input to another. This is useful for complex data processing:

#!/bin/bash
cat file.txt | grep "pattern"

This command reads the contents of file.txt and filters lines containing the specified pattern.

Command Substitution ($())

You can use command substitution to embed the output of a command within a string:

#!/bin/bash
disk_space=$(df -h)
echo "Disk space information:"
echo "$disk_space"

Here, the df -h command's output is assigned to the disk_space variable.

12. Best Practices

Writing clean, readable, and maintainable shell scripts is essential. Here are some best practices to follow:

Commenting Your Code

Use comments to explain your code's purpose and any non-trivial logic. For example:

#!/bin/bash
# This script calculates the sum of two numbers.

Indentation

Use consistent indentation (usually with spaces) to improve code readability:

#!/bin/bash
if [ "$score" -ge 90 ]; then
echo "Grade: A"
elif [ "$score" -ge 80 ]; then
echo "Grade: B"
else
echo "Grade: C"
fi

Error Handling

Handle errors gracefully by checking the exit codes of commands and providing meaningful error messages.

Modularity

Break your script into functions to improve code organization and reusability.

#!/bin/bash
calculate_sum() {
# Function logic here
}

Use Descriptive Variable Names

Choose descriptive variable names to make your code self-explanatory:

#!/bin/bash
name="John"
age=30

Avoid Hardcoding Paths

Use variables or configuration files to store file paths and other constants instead of hardcoding them directly into your script.

#!/bin/bash
config_file="my_config.cfg"
source "$config_file"

Modularity

Modularity means breaking down your script into smaller, self-contained functions or modules. This practice improves code organization, readability, and reusability. Here's an example:

#!/bin/bash

# Function to greet a person
greet() {
local name=$1
echo "Hello, $name!"
}

# Function to calculate the sum of two numbers
calculate_sum() {
local num1=$1
local num2=$2
local sum=$((num1 + num2))
echo "Sum: $sum"
}

# Main part of the script
name="Alice"
greet "$name"
calculate_sum 5 3